package me.zingon.doc.aop;

import io.jsonwebtoken.Claims;
import me.zingon.doc.exception.ServiceException;
import me.zingon.doc.util.JwtUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * Created by zhidi on 2018-3-26.
 */
@Component
@Aspect
public class ControllerAOP {

    @Value("${jwt.header.token}")
    String TokenKey;

    @Autowired
    HttpServletRequest request;

    @Autowired
    HttpServletResponse response;

    @Autowired
    Properties ymlConfig;

    private List<String> nofilter = new ArrayList<>();
    {
        nofilter.add("me.zingon.doc.controller.UserController.login");
        nofilter.add("me.zingon.doc.controller.UserController.register");
        nofilter.add("me.zingon.doc.controller.UserController.active");
        nofilter.add("me.zingon.doc.controller.UserController.check");
    }

    @Pointcut("execution (* me.zingon.doc.controller..*.*(..))")
    public void formatPointcut() {
    }

    @Around("formatPointcut()")
    public Object around(ProceedingJoinPoint point) {
        Map<String, Object> resultMap = new HashMap<String, Object>(3);
        String errmsg = "ok";
        Object result = null;
        String name=point.getSignature().getDeclaringTypeName()+"."+point.getSignature().getName();
        if(nofilter.stream().filter(n-> n.equals(name)).count() == 0L){
            //没有token
            if(null == request.getHeader(TokenKey)){
                errmsg = "login.notoken";
                resultMap.put("errcode", ymlConfig.getProperty(errmsg));
                resultMap.put("errmsg", errmsg);
                return resultMap;
            }
            //token无效
            String token = request.getHeader(TokenKey);
            Claims claims = JwtUtil.validate(token);
            if (null == claims){
                errmsg = "login.invalid";
                resultMap.put("errcode", ymlConfig.getProperty(errmsg));
                resultMap.put("errmsg", errmsg);
                return resultMap;
            }
            //token还剩5分钟过期，自动延时
            long minuties = (claims.getExpiration().getTime() - System.currentTimeMillis())/1000/60;
            if(minuties < 5 ){
                String newToken = JwtUtil.refresh(claims);
                response.addHeader(TokenKey,newToken);
            }
        }

        try {
            result = point.proceed();
        } catch (Throwable throwable) {
            if(throwable instanceof ServiceException){
                errmsg = ((ServiceException) throwable).getMsg();
            }else {
                throwable.printStackTrace();
                errmsg = "system.error";
            }
        }

        resultMap.put("errcode", ymlConfig.getProperty(errmsg));
        resultMap.put("errmsg", errmsg);
        resultMap.put("data", result);
        return resultMap;
    }

}
